This note provide a introduction to create animation in R using the gganimate package.

What is gganimate?

gganimate is an extension of the ggplot2 package for creating animated ggplots. It provide a range of new functionality that can be added to the plot object in order to customize how it should change with time.

3 main class of functions in gganimate:

Prerequisites

# data wrangling
library(dplyr)
# static plot
library(ggplot2)
# animation
library(gganimate)
# data set
library(gapminder)

Data set

gapminder
## # A tibble: 1,704 x 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Afghanistan Asia       1957    30.3  9240934      821.
##  3 Afghanistan Asia       1962    32.0 10267083      853.
##  4 Afghanistan Asia       1967    34.0 11537966      836.
##  5 Afghanistan Asia       1972    36.1 13079460      740.
##  6 Afghanistan Asia       1977    38.4 14880372      786.
##  7 Afghanistan Asia       1982    39.9 12881816      978.
##  8 Afghanistan Asia       1987    40.8 13867957      852.
##  9 Afghanistan Asia       1992    41.7 16317921      649.
## 10 Afghanistan Asia       1997    41.8 22227415      635.
## # … with 1,694 more rows

Step 1: Create a static plot

stat_scatter <- ggplot(data = gapminder, aes(x = gdpPercap, y=lifeExp, size = pop, colour = country)) +
  geom_point(show.legend = FALSE, alpha = 0.7) +
  # scale the color
  scale_color_viridis_d() +
  # scale the point size
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  labs(x = "GDP per capita", y = "Life expectancy")
stat_scatter

Step 2: Define how the animation should run with transition_*()

Transition function: transition_time() splits the data into subsets based on a variable in the data, the animation go through each subset over time.

Label variables: frame_time. Gives the time that the current frame corresponds to.

stat_scatter +
  # transition function
  transition_time(year) +
  # label variable
  labs(title = "Year: {frame_time}")

filter(gapminder, year == 1952)
## # A tibble: 142 x 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Albania     Europe     1952    55.2  1282697     1601.
##  3 Algeria     Africa     1952    43.1  9279525     2449.
##  4 Angola      Africa     1952    30.0  4232095     3521.
##  5 Argentina   Americas   1952    62.5 17876956     5911.
##  6 Australia   Oceania    1952    69.1  8691212    10040.
##  7 Austria     Europe     1952    66.8  6927772     6137.
##  8 Bahrain     Asia       1952    50.9   120447     9867.
##  9 Bangladesh  Asia       1952    37.5 46886859      684.
## 10 Belgium     Europe     1952    68    8730405     8343.
## # … with 132 more rows

8 ore transition functions:

Use the ? view the R Documentation.

Step 3: Define how the axis scale should change with view_*()

view_follow: set the axis scale follow the in each frame.

stat_scatter +
  # transition function
  transition_time(year) +
  # label variable
  labs(title = "Year: {frame_time}") +
  # view function
  view_follow(fixed_y = TRUE)

5 more view functions:

Use the ? view the R Documentation.

Step 4: Define how data from previous time should be presented in the current time with shadow_*()

shadow_wake() draw a small wake after data by showing the latest frames up to the current.

stat_scatter +
  # transition function
  transition_time(year) +
  # label variable
  labs(title = "Year: {frame_time}") +
  # view function
  view_follow(fixed_y = TRUE) +
  # shadow function
  shadow_wake(wake_length = 0.1, alpha = FALSE)

3 more shadow functions:

Use the ? view the R Documentation.

Step 5: Control how the animate being render with animate()

-fps sets the frames per second (defaults to 10)

anim <- stat_scatter +
  # transition function
  transition_time(year) +
  # label variable
  labs(title = "Year: {frame_time}") +
  # view function
  view_follow(fixed_y = TRUE) +
  # shadow function
  shadow_wake(wake_length = 0.1, alpha = FALSE)

animate(plot = anim, 
        nframes = 80, 
        fps = 5, 
        renderer = gifski_renderer(loop = FALSE))

Step 6: Save the animation in your local computer

anim_save(filename = "anim_lifeExp_gdp.gif", 
          animation = anim,
          nframes = 80, 
          fps = 8)

Reference